package co.fitstart.admin.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.BusinessException;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.annotation.Dynamic;
import com.demo2do.core.support.Page;
import com.demo2do.core.utils.StringUtils;

import co.fitstart.admin.dao.AgentDao;
import co.fitstart.admin.dao.OrderDao;
import co.fitstart.admin.entity.search.AgentSearch;
import co.fitstart.admin.service.AgentService;
import co.fitstart.entity.order.Order;
import co.fitstart.entity.order.OrderType;
import co.fitstart.entity.order.PaymentStatus;
import co.fitstart.entity.user.agent.Agent;
import co.fitstart.entity.user.agent.AgentDiscount;
import co.fitstart.entity.user.agent.AgentRecord;
import co.fitstart.entity.user.agent.DiscountType;
import co.fitstart.entity.user.agent.RecordType;

@Service("agentService")
public class AgentServiceImpl implements AgentService{
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    @Dynamic
    private AgentDao agentDao;
    
    @Dynamic
    private OrderDao orderDao;

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#listAgent(com.demo2do.core.support.Page)
     */
    public List<Agent> listAgent(Page page) {
        List<Agent> result = agentDao.listAgent(page.getBeginIndex(), page.getMaxResultRecords());
        
        page.calculate(result.size());
        return result.size() > page.getEveryPage() ? result.subList(0, page.getEveryPage()) : result;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#listAgent()
     */
    public List<Agent> listAgent() {
        return agentDao.listAgent();
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#search(co.fitstart.admin.entity.search.AgentSearch, com.demo2do.core.support.Page)
     */
    @SuppressWarnings("unchecked")
    public List<Agent> search(AgentSearch agentSearch, Page page) {
        String sentence = agentSearch.buildSentenceTemplate() + " GROUP BY discount.agent";
        List<Agent> result = genericDaoSupport.searchForList(sentence, agentSearch.buildParameters(), page.getBeginIndex(), page.getMaxResultRecords());
        
        page.calculate(result.size());
        return result.size() > page.getEveryPage() ? result.subList(0, page.getEveryPage()) : result;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#load(java.lang.Long)
     */
    public Agent loadAgentByUserId(Long userId) {
        return agentDao.loadAgent(userId);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#create(co.fitstart.entity.user.agent.Agent, co.fitstart.entity.user.agent.DiscountType, java.lang.String, java.lang.String, java.lang.Integer, java.lang.String)
     */
    public void create(Agent agent, DiscountType discountType, String discountOffer, String commission, Integer agentDiscount,
            String userDiscount) {
        Agent originalAgent = this.loadAgentByUserId(agent.getUser().getId());
        if (originalAgent != null) {
            throw new BusinessException("该代言人已存在");
        }
        // 1. create agent
        genericDaoSupport.save(agent);
        
        // 2. create agentDiscount by discountType
        if(discountType.isPayment()) {
            String[] discountOffers = StringUtils.split(discountOffer, ",");
            String[] commissions = StringUtils.split(commission, ",");
            
            for(int i = 0; i < discountOffers.length; i++) {
                int discountOfferFen = new BigDecimal(discountOffers[i]).multiply(new BigDecimal("100")).intValue();
                int commissionFen = new BigDecimal(commissions[i]).multiply(new BigDecimal("100")).intValue();
                
                AgentDiscount agentdiscount = new AgentDiscount(agent, discountType, discountOfferFen, commissionFen);
                genericDaoSupport.save(agentdiscount);
            }
            
            
        } else if (discountType.isDiscount()) {
            
            String[] userDiscounts = StringUtils.split(userDiscount, ",");
            for (String discount : userDiscounts) {
                
                AgentDiscount agentdiscount = new AgentDiscount(agent, discountType, agentDiscount, Integer.parseInt(discount));
                genericDaoSupport.save(agentdiscount);
            }
        }
        
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#deleteAgent(co.fitstart.entity.user.agent.Agent)
     */
    public void deleteAgent(Agent agent) {
        // 1. delete agent
        genericDaoSupport.update(agent.disable());
        
        // 2. delete agentDiscount
        agentDao.deleteAgentDiscount(agent);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#loadAgent(java.lang.Long)
     */
    public Agent loadAgent(Long agentId) {
        return genericDaoSupport.load(Agent.class, agentId);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#listAgentDiscount(co.fitstart.entity.user.agent.Agent)
     */
    public List<AgentDiscount> listAgentDiscount(Agent agent) {
        return agentDao.listAgentDiscount(agent);
    }

    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#listAgentOrder(co.fitstart.entity.user.agent.Agent)
     */
    public List<Order> listAgentOrder(Agent agent) {
        return orderDao.list(OrderType.ONLINE, agent, PaymentStatus.PAID);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#createAgentDiscount(co.fitstart.entity.user.agent.Agent, co.fitstart.entity.user.agent.DiscountType, java.lang.String, java.lang.String)
     */
    public void createAgentDiscount(Agent agent, DiscountType discountType, String discount, String commission) {
        String[] discounts = StringUtils.split(discount, ",");
        String[] commissions = StringUtils.split(commission, ",");
        if(discountType.isPayment()) {
            
            
            for(int i = 0; i < discounts.length; i++) {
                int discountFen = new BigDecimal(discounts[i]).multiply(new BigDecimal("100")).intValue();
                int commissionFen = new BigDecimal(commissions[i]).multiply(new BigDecimal("100")).intValue();
                
                AgentDiscount agentdiscount = new AgentDiscount(agent, discountType, discountFen, commissionFen);
                genericDaoSupport.save(agentdiscount);
            }
            
            
        } else if (discountType.isDiscount()) {
            
            for (String commiss : commissions) {
                
                AgentDiscount agentdiscount = new AgentDiscount(agent, discountType, Integer.parseInt(discounts[0]), Integer.parseInt(commiss));
                genericDaoSupport.save(agentdiscount);
            }
        }
        
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#deleteAgentDiscount(co.fitstart.entity.user.agent.AgentDiscount)
     */
    public void deleteAgentDiscount(AgentDiscount agentDiscount) {
        genericDaoSupport.update(agentDiscount.disable());
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#listAgentRecord(co.fitstart.entity.user.agent.Agent, com.demo2do.core.support.Page)
     */
    public List<AgentRecord> listAgentRecord(Agent agent, Page page) {
        List<AgentRecord> result = agentDao.listAgentRecord(agent, new RecordType[]{RecordType.WITHDRAWING, RecordType.WITHDRAWED}, page.getBeginIndex(), page.getMaxResultRecords());
        
        page.calculate(result.size());
        return result.size() > page.getEveryPage() ? result.subList(0, page.getEveryPage()) : result;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#listAgentRecord(co.fitstart.entity.user.agent.RecordType, com.demo2do.core.support.Page)
     */
    public List<AgentRecord> listAgentRecord(RecordType recordType, Page page) {
        List<AgentRecord> result = agentDao.listAgentRecord(recordType, page.getBeginIndex(), page.getMaxResultRecords());
        
        page.calculate(result.size());
        return result.size() > page.getEveryPage() ? result.subList(0, page.getEveryPage()) : result;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#listAgentRecord(co.fitstart.entity.user.agent.RecordType, java.util.Date, java.util.Date)
     */
    public List<AgentRecord> listAgentRecord(RecordType type, Date beginTime, Date endTime) {
        List<AgentRecord> agentRecords = new ArrayList<AgentRecord>();
        
        if(type.isWithdrawing()) {
            agentRecords = agentDao.listWithdrawingAgentRecord(type, beginTime, endTime);
        } else {
            agentRecords = agentDao.listWithdrawedAgentRecord(type, beginTime, endTime);
        }
        return agentRecords;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#loadAgentRecord(java.lang.Long)
     */
    public AgentRecord loadAgentRecord(Long agentRecordId) {
        return genericDaoSupport.load(AgentRecord.class, agentRecordId);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.service.AgentService#pay(co.fitstart.entity.user.agent.Agent, co.fitstart.entity.user.agent.AgentRecord)
     */
    public void pay(Agent agent, AgentRecord agentRecord) {
        // change agentRecord type
        genericDaoSupport.update(agentRecord.pay());
        
        // update agent
        genericDaoSupport.update(agent.pay(agentRecord.getOffer()));
        
    }
}
